package com.fulihui.usercore.core.processor.auth;

import com.fulihui.usercore.common.util.Errors;
import com.fulihui.usercore.common.util.PasswordUtil;
import com.fulihui.usercore.dal.dataobj.LoginDO;
import com.fulihui.usercore.dto.UserDTO;
import com.fulihui.usercore.enums.BooleanValueEnum;
import com.fulihui.usercore.enums.UserGenderEnum;
import com.fulihui.usercore.enums.UserRegisterTypeEnum;
import com.fulihui.usercore.enums.UserStateEnum;
import com.fulihui.usercore.request.auth.AbstractAuthRequest;
import com.fulihui.usercore.request.auth.AccountAuthRequest;
import com.fulihui.usercore.sdk.domain.SignTypeEnum;
import org.apache.commons.lang3.RandomStringUtils;
import org.near.servicesupport.error.InvokeServiceException;
import org.near.toolkit.common.StringUtil;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static java.util.Collections.singletonList;

/**
 * @author Willard.Hu on 2016/11/18 0018.
 */
@Component("accountLoginAuthProcessor")
public class AccountLoginAuthProcessor extends AbstractAuthProcessor {

    @Override
    public String authType() {
        return UserRegisterTypeEnum.ACCOUNT.getCode();
    }

    @Override
    public String login(AbstractAuthRequest request) {
        AccountAuthRequest accountAuthRequest = (AccountAuthRequest) request;
        String loginId = accountAuthRequest.getLoginId();
        LoginDO saved = userLoginRepository.queryByPK(loginId);
        if (saved == null) {
            throw new InvokeServiceException(Errors.User.NOT_FOUND_USER);
        }
        if (!PasswordUtil.passwordsMatch(loginId, accountAuthRequest.getPassword(),
                saved.getSalt(), saved.getPassword())) {
            throw new InvokeServiceException(Errors.User.PASSWORD_FAILED);
        }
        String userId = saved.getUserId();
        checkLoginUserState(userId);
        signPublish(request, userId, SignTypeEnum.SIGN_IN);
        asyncSignInExecute(userId, request);
        return userId;
    }

    /**
     * 重写注册方法，验证 验证码，然后调用父register通用方法
     * @param request
     * @return
     */
    @Override
    public String register(AbstractAuthRequest request) {
        AccountAuthRequest accountAuthRequest = (AccountAuthRequest) request;
        if (!checkSmsCode(accountAuthRequest.getLoginId(), accountAuthRequest.getVcode(),
                accountAuthRequest.getVcodeNamespace())) {
            throw new InvokeServiceException(Errors.VCode.VCODE_VALIDATION_FAILS);
        }
        return super.register(request);
    }
    /**
     * 重写父类方法，加入密码注册
     * @param request {@link AbstractAuthRequest} 的子类
     * @return {@link LoginDO}
     */
    @Override
    protected LoginDO toLoginModel(String userId, AbstractAuthRequest request) {
        AccountAuthRequest accountAuthRequest = (AccountAuthRequest) request;
        LoginDO loginDO = new LoginDO();
        loginDO.setLoginId(accountAuthRequest.getLoginId());
        loginDO.setUserId(userId);
        loginDO.setSalt(RandomStringUtils.randomAlphanumeric(16));
        loginDO.setPassword(PasswordUtil.encryptPassword(loginDO.getLoginId(),accountAuthRequest.getPassword(),loginDO.getSalt()));
        return loginDO;
    }
    @Override
    protected UserDTO toUserModel(AbstractAuthRequest request) {
        AccountAuthRequest accountAuthRequest = (AccountAuthRequest) request;
        UserDTO userDTO = new UserDTO();
        userDTO.setRegisterType(authType());
        userDTO.setRegisterSource(request.getRegisterSource());
        userDTO.setGender(UserGenderEnum.UNKNOW.getCode());
        //// FIXME: 2017/6/13 H5传头像和昵称
        if (StringUtil.isNotBlank(accountAuthRequest.getNickname())){
            userDTO.setNickname(accountAuthRequest.getNickname());
        }else{
            userDTO.setNickname(nicknameGenerator.generate());
        }
        if (accountAuthRequest.getSex() == 1) {
            userDTO.setGender(UserGenderEnum.MEN.getCode());
        } else if (accountAuthRequest.getSex() == 2) {
            userDTO.setGender(UserGenderEnum.WOMEN.getCode());
        } else {
            userDTO.setGender(UserGenderEnum.UNKNOW.getCode());
        }
        //头像
        if (StringUtil.isNotBlank(accountAuthRequest.getHeadImg())){
            userDTO.setHeadImg(accountAuthRequest.getHeadImg());
        }

        // 快捷登陆账号就是手机号
        userDTO.setMobileNo(request.getLoginId());
        userDTO.setMobileVerified(BooleanValueEnum.TRUE.isTrue());

        userDTO.setState(UserStateEnum.NOMAL.getCode());
        userDTO.setRoleCode("USER_NOMAL");
        userDTO.setProvince(request.getProvince());
        userDTO.setCity(request.getCity());
        Date now = new Date();
        userDTO.gmtCreate(now);
        userDTO.lastLogin(now);
        userDTO.setErduoVersion(request.getErduoVersion());

        if (request.getUsedProduct() != null) {
            userDTO.setUsedProducts(singletonList(request.getUsedProduct()));
        }

        Map<String, Object> param = new HashMap<>();
        if (StringUtil.isNotBlank(request.getUserIP())) {
            param.put("userIp", request.getUserIP());
        }
        if (param.size() > 0) {
            userDTO.setExtInfo(param);
        }

        return userDTO;
    }
}
